package quartz_distributed;

import com.google.common.collect.Maps;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;

import javax.sql.DataSource;
import java.util.Map;
import java.util.Properties;

/**
 * Quartz定时任务配置
 * @author yunlongpang 2017/11/29
 */
@Configuration
public class SchedledConfiguration {

    /**
     * 定时器延迟启动时间
     */
    private static final int START_DELAY_TIME = 10;

    @Autowired
    private MyQuartzJobFactory myQuartzJobFactory;

    @Bean(name = "healthCheckJobDetail")
    public JobDetailFactoryBean healthCheckJobDetail() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(HealthCheckTask.class);
        //设置任务分组:多任务时使用
        jobDetailFactoryBean.setGroup("check-health");
        //设置任务名称
        jobDetailFactoryBean.setName("health-diagnose");
        return jobDetailFactoryBean;
    }

    @Bean(name = "healthCheckTrigger")
    public SimpleTriggerFactoryBean healthCheckTrigger(@Qualifier("healthCheckJobDetail") JobDetailFactoryBean healthCheckJobDetail) {
        SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean();
        trigger.setJobDetail(healthCheckJobDetail.getObject());
        //设置任务分组:多任务时使用
        trigger.setGroup("check-health");
        //设置任务名称
        trigger.setName("health-diagnose");
        trigger.setRepeatInterval(HealthCheckTask.POLL_FIXED_TIME * HealthCheckTask.POLL_FIXED_TIME_UNIT);
        return trigger;
    }

    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactoryBean(Trigger healthCheckTrigger, DataSource dataSource) {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(myQuartzJobFactory);
        //设置数据源
        schedulerFactoryBean.setDataSource(dataSource);
        schedulerFactoryBean.setQuartzProperties(getSchedulerProperties());
        //应用启动后延迟一定时间启动
        schedulerFactoryBean.setStartupDelay(START_DELAY_TIME);
        //注册触发器
        schedulerFactoryBean.setTriggers(healthCheckTrigger);
        //设置注入的Bean
        Map<String, Object> map = Maps.newHashMap();
        schedulerFactoryBean.setSchedulerContextAsMap(map);
        return schedulerFactoryBean;
    }

    /**
     * 配置相关设置
     * @return Properties
     */
    private Properties getSchedulerProperties() {
        Properties quartzProperties = new Properties();
        quartzProperties.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        quartzProperties.put("org.quartz.scheduler.instanceId", "AUTO");
        //集群模式，高可用，一台机器挂了，其他机器可以感知并接手
        quartzProperties.put("org.quartz.jobStore.isClustered", "true");
        //检测失败实例的频率
        quartzProperties.put("org.quartz.jobStore.clusterCheckinInterval", "60000");
        //设置表前缀
        quartzProperties.put("org.quartz.jobStore.tablePrefix", "poller_");
        //定时任务执行线程名称
        quartzProperties.put("org.quartz.threadPool.threadNamePrefix", "scheduler-health-diagnose");
        //Shutdown Hook(通过捕捉JVM关闭时的事件来关闭调度器)插件
        quartzProperties.put("org.quartz.plugin.shutdownHook.class", "org.quartz.plugins.management.ShutdownHookPlugin");
        quartzProperties.put("org.quartz.plugin.shutdownHook.cleanShutdown", true);
        return quartzProperties;
    }

}
